
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.IO;
using System.Xml;

namespace Swaf.Messaging
{
	[Serializable] 
	public class QueueConnectionInfo: IMessagingConnectionInfo, IComparable, ICloneable
	{
		//private string m_id = null;
		private string m_queueName=null;
		private string m_type=null;
		private string m_handlername=null;
		private string m_handlermethod=null;
		private string m_hostname=null;
		private string m_channel=null;
		private string m_port = "1414";
		private string m_queuemanager=null;
		private int m_listenerStartDelay = 1000;
		private int m_maxDepth = 1000000;
		private int m_depth = 0;
		private bool m_create = false;
		private bool m_clusterQueue = false;
		private int m_maxReadMilliseconds = 0;
		private int m_maxReadCount = 0;
		private int m_maxIdleMilliseconds = 0;
		private string m_scheduleInterval = "30 sec";
		private int m_maxThreads = 3;
		private int m_minThreads = 10;
		private string m_destinationQueueName = null;
		private bool m_readToEnd = true;  
		private string m_subscriberName = null;
		private string m_publisherName = null;
		private bool m_open = false;
		private bool m_persistent = false;
		private string m_message;
		private string m_correlationID = null;
		private string m_retryQueueName = null;
		private int m_retryCountBeforeAbort = 0;
		private int m_retryInterval = 0;
		private bool m_useTransactions = false;
		private bool m_outputOnly = false;

		//MJD1: New stuff added after ODSI version moved here.
		private string m_uniqueId = null;
		private string m_messagingSystemId = null;
		private static int s_uniqueId = 0;

		//MJD1: Stuff from ODSI version not needed now.
		//private QueueMessageLabelData m_appData;
		//private AccountingTokenData m_accountingTokenData;
		//private QueueAction m_action = QueueAction.None;

		public QueueConnectionInfo()
		{
		}

		public QueueConnectionInfo(string queueName, string type, string handlername, string handlermethod, string hostname, string channel, string port, string queuemanager)
		{
			QueueName = queueName;
			Type = type;
			HandlerName = handlername;
			HandlerMethod = handlermethod;
			HostName = hostname;
			Channel = channel;
			m_port = port;
			QueueManager = queuemanager;
		}

		public QueueConnectionInfo(string queueName, string type, string handlername, string handlermethod, string hostname, string channel, string port, string queuemanager, int maxReadMilliseconds, int maxReadCount, int maxIdleMilliseconds, string scheduleInterval, int maxThreads, int minThreads)
		{
			m_queueName = queueName;
			Type = type;
			HandlerName = handlername;
			HandlerMethod = handlermethod;
			HostName = hostname;
			Channel = channel;
			m_port = port;
			QueueManager = queuemanager;
			MaxReadMilliseconds = maxReadMilliseconds;
			MaxReadCount = maxReadCount;
			MaxIdleMilliseconds = maxIdleMilliseconds;
			ScheduleInterval = scheduleInterval;
			MinThreads = minThreads;
			MaxThreads = maxThreads;
		}
		public QueueConnectionInfo(string queueName, string destinationQueueName, string type, string handlername, string handlermethod, string hostname, string channel, string port, string queuemanager, int maxReadMilliseconds, int maxReadCount, int maxIdleMilliseconds, string scheduleInterval, int maxThreads, int minThreads)
		{
			QueueName = queueName;
			DestinationQueueName = destinationQueueName;
			Type = type;
			HandlerName = handlername;
			HandlerMethod = handlermethod;
			HostName = hostname;
			Channel = channel;
			m_port = port;
			QueueManager = queuemanager;
			MaxReadMilliseconds = maxReadMilliseconds;
			MaxReadCount = maxReadCount;
			MaxIdleMilliseconds = maxIdleMilliseconds;
		
			ScheduleInterval = scheduleInterval;
			MinThreads = minThreads;
			MaxThreads = maxThreads;
		}

		//MJD2
		#region ICloneable Members

		public object Clone()
		{
			QueueConnectionInfo clone = new QueueConnectionInfo();
			//clone.m_id = this.m_id;
			clone.m_queueName= this.m_queueName;
			clone.m_type=this.m_type;
			clone.m_handlername=this.m_handlername;
			clone.m_handlermethod=this.m_handlermethod;
			clone.m_hostname=this.m_hostname;
			clone.m_channel=this.m_channel;
			clone.m_port = this.m_port;
			clone.m_queuemanager=this.m_queuemanager;
			clone.m_listenerStartDelay = this.m_listenerStartDelay;
			clone.m_maxDepth = this.m_maxDepth;
			clone.m_depth = this.m_depth;
			clone.m_create = this.m_create;
			clone.m_clusterQueue = this.m_clusterQueue;
			clone.m_maxReadMilliseconds = this.m_maxReadMilliseconds;
			clone.m_maxReadCount = this.MaxReadCount;
			clone.m_maxIdleMilliseconds = this.m_maxIdleMilliseconds;
			clone.m_destinationQueueName = this.m_destinationQueueName;
			clone.m_readToEnd = this.m_readToEnd;
			clone.m_subscriberName = this.m_subscriberName;
			clone.m_publisherName = this.m_publisherName;
			clone.m_open = this.m_open;
			clone.m_persistent = this.m_persistent;
			clone.m_message = this.m_message;
			clone.m_correlationID = this.m_correlationID;
			clone.m_retryQueueName = this.m_retryQueueName;
			clone.m_retryCountBeforeAbort = this.m_retryCountBeforeAbort;
			clone.m_retryInterval = this.m_retryInterval;
			clone.m_useTransactions = this.m_useTransactions;
			clone.m_messagingSystemId = this.m_messagingSystemId;
			return clone;
		}

		#endregion

		//MJD1
		public QueueConnectionInfo(XmlElement el)
		{
			initializeFromElement(el);
		}

		protected void initializeFromElement(XmlElement el)
		{
			try 
			{
				this.MessagingSystemId = el.Name;
				XmlNodeList children = el.ChildNodes;
				this.QueueName = el.GetAttribute("name");

				Type thisType = this.GetType();
				foreach(XmlNode node in children)
				{
                    if (node is XmlElement)
                    {
                        XmlElement childEl = node as XmlElement;
                        switch (childEl.Name.ToLower())
                        {
                            case "messagingsystem":
                                this.MessagingSystemId = childEl.InnerText;
                                break;
                            case "port":
                                this.Port = Int32.Parse(childEl.InnerText.Trim());
                                break;
                            case "hostname":
                                this.HostName = childEl.InnerText;
                                break;
                            case "channel":
                                this.Channel = childEl.InnerText;
                                break;
                            case "queuemanager":
                                this.QueueManager = childEl.InnerText;
                                break;
                            case "queuename":
                                this.QueueName = childEl.InnerText;
                                break;
                            case "scheduleinterval":
                                this.ScheduleInterval = childEl.InnerText;
                                break;
                            case "readtoend":
                                this.ReadToEnd = Convert.ToBoolean(childEl.InnerText);
                                break;
                            case "type":
                                this.Type = childEl.InnerText;
                                break;
                            case "listenerstartdelay":
                                this.ListenerStartDelay = Convert.ToInt32(childEl.InnerText);
                                break;
                            case "maxreadmilliseconds":
                                this.MaxReadMilliseconds = Convert.ToInt32(childEl.InnerText);
                                break;
                            case "maxthreads":
                                this.MaxThreads = Convert.ToInt32(childEl.InnerText);
                                break;
                            case "minthreads":
                                this.MinThreads = Convert.ToInt32(childEl.InnerText);
                                break;
                        }
                    }
				}
			}
			catch(Cmn.ReflectionException)
			{
				//TODO: Throw some other kind of exception.
                throw;
			}
			catch(Exception)
			{
				//TODO: Throw some other kind of exception.
                throw;
			}
		}

		public string UniqueId
		{
			get
			{
				//Multi-threaded lazy load.
				if(m_uniqueId == null)
				{
					lock(this)
					{
						//Unique id for QueueConnectionInfo combines useful info with unique number.
						if(m_uniqueId == null)
							m_uniqueId = QueueManager + QueueName + ++s_uniqueId;
					}
				}
				return m_uniqueId;
			}
		}

		public string MessagingSystemId
		{
			get
			{
				return m_messagingSystemId;
			}
			set
			{
				m_messagingSystemId = value;
			}
		}

		public bool UseTransactions
		{
			get{return m_useTransactions;}
			set{m_useTransactions = value;}
		}

		public string Xml
		{
			get
			{
				StringWriter writer =new StringWriter(); 
				XmlTextWriter xmlOut = new XmlTextWriter(writer);
				xmlOut.WriteStartElement(this.MessagingSystemId);
				xmlOut.WriteElementString("HostName", this.HostName);
				xmlOut.WriteElementString("Channel", this.Channel);
				xmlOut.WriteElementString("Port", this.Port.ToString());
				xmlOut.WriteElementString("QueueManager", this.QueueManager);
				xmlOut.WriteEndElement();
				xmlOut.Close();
				return writer.ToString();
			}
		}
		//--------------------------------------------------------------

		//MJD2
		public string ScheduleInterval {get{return m_scheduleInterval;} set{m_scheduleInterval = value;}}
		public int MaxThreads {get{return m_maxThreads;} set{m_maxThreads = value;}}
		public int MinThreads {get{return m_minThreads;} set{m_minThreads = value;}}
		


		public bool ReadToEnd
		{
			get{return m_readToEnd;}
			set{m_readToEnd = value;}
		}
		public int ListenerStartDelay
		{
			get{return m_listenerStartDelay;}
			set{m_listenerStartDelay = value;}
		}

		public string DestinationQueueName
		{
			get{return m_destinationQueueName;}
			set{m_destinationQueueName = value;}
		}

		public Boolean OutputOnly {set{m_outputOnly = value;}get{return m_outputOnly;}}

		public int MaxReadMilliseconds
		{
			get{return m_maxReadMilliseconds;}
			set{m_maxReadMilliseconds = value;}
		}
	 
		public int MaxReadCount
		{
			get{return m_maxReadCount;}
			set{m_maxReadCount = value;}
		}
		 
		public int MaxIdleMilliseconds
		{
			get{return m_maxIdleMilliseconds;}
			set{m_maxIdleMilliseconds = value;}
		}


		public string QueueName
		{
			get{return Application.globalApp.resMgr.resolve(m_queueName);}
			set{m_queueName=value;}
		}

		public string Type
		{
			get{return m_type;}
			set{m_type=value;}
		}

		public string HandlerName
		{
			get{return m_handlername;}
			set{m_handlername=value;}
		}

		public string HandlerMethod
		{
			get{return m_handlermethod;}
			set{m_handlermethod=value;}
		}

		public string HostName
		{
			get{return Application.globalApp.resMgr.resolve(m_hostname);}
			set{m_hostname=value;}
		}

		public string Channel
		{
			get{return Application.globalApp.resMgr.resolve(m_channel);}
			set{m_channel=value;}
		}

		public int Port
		{
			get{return int.Parse(Application.globalApp.resMgr.resolve(m_port));}
			set{m_port=value.ToString();}
		}

		public string QueueManager
		{
			get{return Application.globalApp.resMgr.resolve(m_queuemanager);}
			set{m_queuemanager=value;}
		}
	 
		public int MaxDepth
		{
			get{return m_maxDepth;}
			set{m_maxDepth = value;}
		}
		public int Depth
		{
			get{return m_depth;}
			set{m_depth = value;}
		}

		public bool Create
		{
			get{return m_create;}
			set{m_create = value;}
		}
		public bool ClusterQueue
		{
			get{return m_clusterQueue;}
			set{m_clusterQueue = value;}
		}
		public string PublisherName
		{
			get{return m_publisherName;}
			set{m_publisherName = value;}
		}
		public string SubscriberName
		{
			get{return m_subscriberName;}
			set{m_subscriberName = value;}
		}
		public bool Open
		{
			get{return m_open;}
			set{m_open = value;}
		}
		public bool Persistent
		{
			get{return m_persistent;}
			set{m_persistent = value;}
		}

		
		//to send message
		public string Message
		{
			get{return m_message;}
			set{m_message = value;}
			
		}
			 
		/*
		public QueueAction Action
		{
			get{return m_action;}
			set{m_action = value;}
		}

				public QueueMessageLabelData AppData
		{
			get{return m_appData;}
			set{m_appData = value;}
		}
		
		public AccountingTokenData AccountingTokenData
		{
			get{return m_accountingTokenData;}
			set{m_accountingTokenData = value;}
		}
		*/
 
		public string CorrelationID
		{  
			get{return m_correlationID;}
			set{m_correlationID = value;}
		}

		/*
		public string ID
		{
			get{return m_id;}
			set{m_id = value;}
		}
		*/

		public string RetryQueueName
		{
			get{return m_retryQueueName;}
			set{m_retryQueueName = value;}
		}

		public int RetryCountBeforeAbort
		{
			get{return m_retryCountBeforeAbort;}
			set{m_retryCountBeforeAbort = value;}
		}
 
		public int RetryInterval
		{
			get{return m_retryInterval;}
			set{m_retryInterval = value;}
		
		}

		public IMessagingConnection createConnection()
		{
			IMessagingConnection conn = (IMessagingConnection)
				Application.globalApp.factories["MessagingConnections"].createFromNickName(MessagingSystemId, this);
			return conn;
		}

		 

		public int CompareTo(object obj)              
		{
			if ( obj == null) return 1;                   
			
			if ( !(obj is QueueConnectionInfo) )                    
			{ 
				throw new ArgumentException();                    
			}                    
			
			                 
			QueueConnectionInfo eObj = (QueueConnectionInfo) obj;
			return (this.QueueName.CompareTo(eObj.QueueName));                     
			          
		}
	}//class
}//namespace
